convert dg100 to Format class (#557)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Thu, 14 May 2020 17:19:24 +0000 (11:19 -0600)
committerGitHub <noreply@github.com>
Thu, 14 May 2020 17:19:24 +0000 (11:19 -0600)
* convert dg100 format to Format class.

* regenerate dependencies for dg100 format.

* whitespace

CMakeLists.txt
GPSBabel.pro
Makefile.in
dg-100.cc
dg-100.h [new file with mode: 0644]
vecs.h

index 1700809d8d12c9036c183081f7f8029766f7bd27..b16b9ca5f40552f7000b80779f3b1bc8bc7c49ab 100644 (file)
@@ -107,6 +107,7 @@ set(HEADERS
   cet_util.h
   csv_util.h
   defs.h
+  dg-100.h
   energympro.h
   explorist_ini.h
   filter.h
index ca87868140c5350f62d1ff405f7d5c6e3a4a9169..8ff6d192e4fff67e28ab48e51281de0cfa409659 100644 (file)
@@ -92,6 +92,7 @@ HEADERS =  \
        cet_util.h \
        csv_util.h \
        defs.h \
+       dg-100.h \
        energympro.h \
        explorist_ini.h \
        filter.h \
index c173d05ea70cd464d9edc9a026b6b996ac9491d4..4b8bba108a7f08f2eeb02588455c4daf96b45fd6 100644 (file)
@@ -474,7 +474,7 @@ destinator.o: destinator.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   strptime.h
 dg-100.o: dg-100.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
-  gbser.h
+  dg-100.h format.h gbser.h
 discard.o: discard.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
   discard.h filter.h
@@ -508,11 +508,11 @@ filter_vecs.o: filter_vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   duplicate.h height.h heightgrid.h interpolate.h nukedata.h polygon.h \
   position.h radius.h reverse_route.h smplrout.h sort.h stackfilter.h \
   swapdata.h trackfilter.h transform.h validate.h gbversion.h vecs.h \
-  format.h energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
-  globalsat_sport.h gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h \
-  kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h \
-  qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h subrip.h \
-  unicsv.h src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h \
+  dg-100.h format.h energympro.h garmin_fit.h geojson.h src/core/file.h \
+  ggv_bin.h globalsat_sport.h gpx.h src/core/xmlstreamwriter.h \
+  src/core/xmltag.h kml.h xmlgeneric.h legacyformat.h lowranceusr.h \
+  mynav.h nmea.h qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h \
+  subrip.h unicsv.h src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h \
   jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
   jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
@@ -534,7 +534,7 @@ garmin.o: garmin.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
   jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
   jeeps/gpsrqst.h garmin_tables.h grtcirc.h jeeps/gpsserial.h vecs.h \
-  energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
+  dg-100.h energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
   globalsat_sport.h gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h \
   kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h \
   qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h subrip.h \
@@ -821,7 +821,7 @@ maggeo.o: maggeo.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
 magproto.o: magproto.cc defs.h config.h zlib/zlib.h zlib/zconf.h \
   formspec.h inifile.h gbfile.h session.h src/core/datetime.h \
   src/core/optional.h explorist_ini.h format.h gbser.h magellan.h vecs.h \
-  energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
+  dg-100.h energympro.h garmin_fit.h geojson.h src/core/file.h ggv_bin.h \
   globalsat_sport.h gpx.h src/core/xmlstreamwriter.h src/core/xmltag.h \
   kml.h xmlgeneric.h legacyformat.h lowranceusr.h mynav.h nmea.h \
   qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h subrip.h \
@@ -836,7 +836,7 @@ main.o: main.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   discard.h duplicate.h height.h heightgrid.h interpolate.h nukedata.h \
   polygon.h position.h radius.h reverse_route.h smplrout.h sort.h \
   stackfilter.h swapdata.h trackfilter.h transform.h validate.h format.h \
-  src/core/file.h src/core/usasciicodec.h vecs.h energympro.h \
+  src/core/file.h src/core/usasciicodec.h vecs.h dg-100.h energympro.h \
   garmin_fit.h geojson.h ggv_bin.h globalsat_sport.h gpx.h \
   src/core/xmlstreamwriter.h src/core/xmltag.h kml.h xmlgeneric.h \
   legacyformat.h lowranceusr.h mynav.h nmea.h qstarz_bl_1000.h random.h \
@@ -1060,15 +1060,16 @@ vcf.o: vcf.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   jeeps/gpsmath.h jeeps/gpsport.h
 vecs.o: vecs.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h \
-  vecs.h format.h energympro.h garmin_fit.h geojson.h src/core/file.h \
-  ggv_bin.h globalsat_sport.h gpx.h src/core/xmlstreamwriter.h \
-  src/core/xmltag.h kml.h xmlgeneric.h legacyformat.h lowranceusr.h \
-  mynav.h nmea.h qstarz_bl_1000.h random.h shape.h shapelib/shapefil.h \
-  subrip.h unicsv.h src/core/textstream.h xcsv.h garmin_fs.h jeeps/gps.h \
-  jeeps/../defs.h jeeps/gpsport.h jeeps/gpsdevice.h jeeps/gpssend.h \
-  jeeps/gpsread.h jeeps/gpsutil.h jeeps/gpsapp.h jeeps/gpsprot.h \
-  jeeps/gpscom.h jeeps/gpsfmt.h jeeps/gpsmath.h jeeps/gpsmem.h \
-  jeeps/gpsrqst.h yahoo.h gbversion.h src/core/logging.h
+  vecs.h dg-100.h format.h energympro.h garmin_fit.h geojson.h \
+  src/core/file.h ggv_bin.h globalsat_sport.h gpx.h \
+  src/core/xmlstreamwriter.h src/core/xmltag.h kml.h xmlgeneric.h \
+  legacyformat.h lowranceusr.h mynav.h nmea.h qstarz_bl_1000.h random.h \
+  shape.h shapelib/shapefil.h subrip.h unicsv.h src/core/textstream.h \
+  xcsv.h garmin_fs.h jeeps/gps.h jeeps/../defs.h jeeps/gpsport.h \
+  jeeps/gpsdevice.h jeeps/gpssend.h jeeps/gpsread.h jeeps/gpsutil.h \
+  jeeps/gpsapp.h jeeps/gpsprot.h jeeps/gpscom.h jeeps/gpsfmt.h \
+  jeeps/gpsmath.h jeeps/gpsmem.h jeeps/gpsrqst.h yahoo.h gbversion.h \
+  src/core/logging.h
 vidaone.o: vidaone.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
   inifile.h gbfile.h session.h src/core/datetime.h src/core/optional.h
 vitosmt.o: vitosmt.cc defs.h config.h zlib/zlib.h zlib/zconf.h formspec.h \
index 722efcd3d0240eb9668d1b5c8241fa449395c68f..33760b1732b18f2f46890b20e336de897118e21c 100644 (file)
--- a/dg-100.cc
+++ b/dg-100.cc
 #include <QtCore/QScopedArrayPointer>  // for QScopedArrayPointer
 #include <QtCore/QString>              // for QString
 #include <QtCore/QTime>                // for QTime
-#include <QtCore/QVector>              // for QVector
 #include <QtCore/Qt>                   // for TextDate, UTC
 #include <QtCore/QtGlobal>             // for qPrintable
 
 #include "defs.h"
+#include "dg-100.h"
 #include "gbfile.h"                    // for gbfread, gbfclose, gbfgetc, gbfopen, gbfile
 #include "gbser.h"                     // for gbser_deinit, gbser_flush, gbser_init, gbser_read_wait, gbser_readc_wait, gbser_set_speed, gbser_write, gbser_ERROR, gbser_OK, gbser_NOTHING
 
 
 #define MYNAME "DG-100"
 
-struct model_t {
-  const char *name;
-  unsigned speed;
-  int has_trailing_bytes;
-  int has_payload_end_seq;
-  struct dg100_command *commands;
-  unsigned int numcommands;
-};
-
-static const model_t* model;
-
-static void* serial_handle;
-
-static gbfile* fin{nullptr};
-static bool isfile{false};
-
-/* maximum frame size observed so far: 1817 bytes
- *   (dg100cmd_getfileheader returning 150 entries)
- * dg100cmd_getfileheader is the only answer type of variable length,
- * answers of other types are always shorter than 1817 bytes */
-#define FRAME_MAXLEN 4096
-
-enum dg100_command_id {
-  dg100cmd_getconfig     = 0xB7,
-  dg100cmd_setconfig     = 0xB8,
-  dg100cmd_getfileheader = 0xBB,
-  dg100cmd_getfile       = 0xB5,
-  dg100cmd_erase         = 0xBA,
-  dg100cmd_getid         = 0xBF,
-  dg100cmd_setid         = 0xC0,
-  dg100cmd_gpsmouse      = 0xBC,
-  dg200cmd_reset         = 0x80
-};
-
-struct dg100_command {
-  int  id;
-  int  sendsize;
-  int  recvsize;
-  int  trailing_bytes;
-  const char* text;    /* Textual description for debugging */
-};
-
-static struct dg100_command dg100_commands[] = {
+const Dg100Format::dg100_command Dg100Format::dg100_commands[] = {
   { dg100cmd_getfile,        2, 1024,    2, "getfile" },
   /* the getfileheader answer has variable length, -1 is a dummy value */
   { dg100cmd_getfileheader,  2,   -1,    2, "getfileheader"  },
@@ -108,7 +66,7 @@ static struct dg100_command dg100_commands[] = {
   { dg100cmd_gpsmouse,       1,    0,    0, "gpsmouse" }
 };
 
-static struct dg100_command dg200_commands[] = {
+const Dg100Format::dg100_command Dg100Format::dg200_commands[] = {
   { dg100cmd_getfile,        2, 1024,    2, "getfile" },
   /* the getfileheader answer has variable length, -1 is a dummy value */
   { dg100cmd_getfileheader,  2,   -1,    2, "getfileheader"  },
@@ -122,8 +80,9 @@ static struct dg100_command dg200_commands[] = {
 };
 
 /* helper functions */
-static struct dg100_command*
-dg100_findcmd(int id) {
+const Dg100Format::dg100_command*
+Dg100Format::dg100_findcmd(int id) const
+{
   /* linear search should be OK as long as dg100_numcommands is small */
   for (unsigned int i = 0; i < model->numcommands; i++) {
     if (model->commands[i].id == id) {
@@ -134,8 +93,8 @@ dg100_findcmd(int id) {
   return nullptr;
 }
 
-static QDateTime
-bintime2utc(int date, int time)
+QDateTime
+Dg100Format::bintime2utc(int date, int time)
 {
   int sec   = time % 100;
   time /= 100;
@@ -153,8 +112,8 @@ bintime2utc(int date, int time)
   return QDateTime(QDate(year, mon, day), QTime(hour, min, sec), Qt::UTC);
 }
 
-static void
-dg100_debug(const char* hdr, int include_nl, size_t sz, unsigned char* buf)
+void
+Dg100Format::dg100_debug(const char* hdr, int include_nl, size_t sz, unsigned char* buf)
 {
   /* Only give byte dumps for higher debug levels */
   if (global_opts.debug_level < 5) {
@@ -172,8 +131,8 @@ dg100_debug(const char* hdr, int include_nl, size_t sz, unsigned char* buf)
   }
 }
 
-static void
-dg100_log(const char* fmt, ...)
+void
+Dg100Format::dg100_log(const char* fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
@@ -185,8 +144,8 @@ dg100_log(const char* fmt, ...)
 
 
 /* TODO: check whether negative lat/lon (West/South) are handled correctly */
-static float
-bin2deg(int val)
+float
+Dg100Format::bin2deg(int val) const
 {
   /* Assume that val prints in decimal digits as [-]dddmmffff
    * ddd:  degrees
@@ -208,8 +167,8 @@ bin2deg(int val)
   return(deg);
 }
 
-static void
-process_gpsfile(uint8_t data[], route_head** track)
+void
+Dg100Format::process_gpsfile(uint8_t data[], route_head** track) const
 {
   const int recordsizes[3] = {8, 20, 32};
 
@@ -285,8 +244,8 @@ process_gpsfile(uint8_t data[], route_head** track)
   }
 }
 
-static uint16_t
-dg100_checksum(const uint8_t buf[], int count)
+uint16_t
+Dg100Format::dg100_checksum(const uint8_t buf[], int count)
 {
   uint16_t sum = 0;
 
@@ -299,8 +258,8 @@ dg100_checksum(const uint8_t buf[], int count)
 }
 
 /* communication functions */
-static size_t
-dg100_send(uint8_t cmd, const void* payload, size_t param_len)
+size_t
+Dg100Format::dg100_send(uint8_t cmd, const void* payload, size_t param_len) const
 {
   uint8_t frame[FRAME_MAXLEN];
 
@@ -349,7 +308,7 @@ dg100_send(uint8_t cmd, const void* payload, size_t param_len)
   }
 
   if (global_opts.debug_level) {
-    struct dg100_command* cmdp = dg100_findcmd(cmd);
+    const dg100_command* cmdp = dg100_findcmd(cmd);
 
     dg100_debug(n == 0 ? "Sent: " : "Error Sending:",
                 1, framelen, frame);
@@ -363,8 +322,8 @@ dg100_send(uint8_t cmd, const void* payload, size_t param_len)
   return (n);
 }
 
-static int
-dg100_recv_byte()
+int
+Dg100Format::dg100_recv_byte() const
 {
   int result;
   if (isfile) {
@@ -387,8 +346,8 @@ dg100_recv_byte()
   return result;
 }
 
-static int
-dg100_read_wait(void* handle, void* buf, unsigned len, unsigned ms)
+int
+Dg100Format::dg100_read_wait(void* handle, void* buf, unsigned len, unsigned ms) const
 {
   if (isfile) {
     return gbfread(buf, 1, len, fin);
@@ -400,8 +359,8 @@ dg100_read_wait(void* handle, void* buf, unsigned len, unsigned ms)
 /* payload returns a pointer into a static buffer (which also contains the
  * framing around the data), so the caller must copy the data before calling
  * this function again */
-static int
-dg100_recv_frame(struct dg100_command** cmdinfo_result, uint8_t** payload)
+int
+Dg100Format::dg100_recv_frame(const dg100_command** cmdinfo_result, uint8_t** payload) const
 {
   static uint8_t buf[FRAME_MAXLEN];
   uint16_t payload_end_seq;
@@ -458,7 +417,7 @@ dg100_recv_frame(struct dg100_command** cmdinfo_result, uint8_t** payload)
     cmd = dg100cmd_setconfig;
   }
 
-  struct dg100_command* cmdinfo = dg100_findcmd(cmd);
+  const dg100_command* cmdinfo = dg100_findcmd(cmd);
   if (!cmdinfo) {
     /* TODO: consume data until frame end signature,
      * then report failure to the caller? */
@@ -530,10 +489,10 @@ dg100_recv_frame(struct dg100_command** cmdinfo_result, uint8_t** payload)
 }
 
 /* return value: number of bytes copied into buf, -1 on error */
-static int
-dg100_recv(uint8_t expected_id, void* buf, unsigned int len)
+int
+Dg100Format::dg100_recv(uint8_t expected_id, void* buf, unsigned int len) const
 {
-  struct dg100_command* cmdinfo;
+  const dg100_command* cmdinfo;
   uint8_t* data;
 
   int n = dg100_recv_frame(&cmdinfo, &data);
@@ -559,10 +518,10 @@ dg100_recv(uint8_t expected_id, void* buf, unsigned int len)
 
 /* the number of bytes to be sent is determined by cmd,
  * count is the size of recvbuf */
-static int
-dg100_request(uint8_t cmd, const void* sendbuf, void* recvbuf, size_t count)
+int
+Dg100Format::dg100_request(uint8_t cmd, const void* sendbuf, void* recvbuf, size_t count) const
 {
-  struct dg100_command* cmdinfo = dg100_findcmd(cmd);
+  const dg100_command* cmdinfo = dg100_findcmd(cmd);
   assert(cmdinfo != nullptr);
   dg100_send(cmd, sendbuf, cmdinfo->sendsize);
 
@@ -582,8 +541,8 @@ dg100_request(uint8_t cmd, const void* sendbuf, void* recvbuf, size_t count)
 }
 
 /* higher level communication functions */
-static QList<int>
-dg100_getfileheaders()
+QList<int>
+Dg100Format::dg100_getfileheaders() const
 {
   QList<int> headers;
   uint8_t request[2];
@@ -623,16 +582,16 @@ dg100_getfileheaders()
   return headers;
 }
 
-static void
-dg100_getconfig()
+void
+Dg100Format::dg100_getconfig() const
 {
   uint8_t answer[45];
 
   dg100_request(dg100cmd_getconfig, nullptr, answer, sizeof(answer));
 }
 
-static void
-dg100_getfile(int16_t num, route_head** track)
+void
+Dg100Format::dg100_getfile(int16_t num, route_head** track) const
 {
   uint8_t request[2];
   uint8_t answer[2048];
@@ -642,8 +601,8 @@ dg100_getfile(int16_t num, route_head** track)
   process_gpsfile(answer, track);
 }
 
-static void
-dg100_getfiles()
+void
+Dg100Format::dg100_getfiles() const
 {
   route_head* track = nullptr;
 
@@ -661,8 +620,8 @@ dg100_getfiles()
   }
 }
 
-static int
-dg100_erase()
+int
+Dg100Format::dg100_erase() const
 {
   uint8_t request[2] = { 0xFF, 0xFF };
   uint8_t answer[4];
@@ -675,29 +634,12 @@ dg100_erase()
   return(0);
 }
 
-/* GPSBabel integration */
-
-static char* erase;
-static char* erase_only;
-
-static
-QVector<arglist_t> dg100_args = {
-  {
-    "erase", &erase, "Erase device data after download",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
-  },
-  {
-    "erase_only", &erase_only, "Only erase device data, do not download anything",
-    "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
-  },
-};
-
 /*******************************************************************************
 * %%%        global callbacks called by gpsbabel main process              %%% *
 *******************************************************************************/
 
-static void
-common_rd_init(const QString& fname)
+void
+Dg100Format::common_rd_init(const QString& fname)
 {
   if (isfile) {
     fin = gbfopen(fname, "rb", MYNAME);
@@ -714,52 +656,26 @@ common_rd_init(const QString& fname)
   }
 }
 
-static void
-dg100_rd_init(const QString& fname)
+void
+Dg100Format::dg100_rd_init(const QString& fname, bool isfile)
 {
-  static const model_t dg100_model = { "DG-100", 115200, 1, 1, dg100_commands, sizeof(dg100_commands) / sizeof(struct dg100_command) };
+  static const model_t dg100_model = { "DG-100", 115200, true, true, dg100_commands, sizeof(dg100_commands) / sizeof(dg100_command) };
   model = &dg100_model;
+  this->isfile = isfile;
   common_rd_init(fname);
 }
 
-static void
-dg100_rd_serial_init(const QString& fname)
-{
-  isfile = false;
-  dg100_rd_init(fname);
-}
-
-static void
-dg100_rd_file_init(const QString& fname)
-{
-  isfile = true;
-  dg100_rd_init(fname);
-}
-
-static void
-dg200_rd_init(const QString& fname)
+void
+Dg100Format::dg200_rd_init(const QString& fname, bool isfile)
 {
-  static const model_t dg200_model = { "DG-200", 230400, 0, 0, dg200_commands, sizeof(dg200_commands) / sizeof(struct dg100_command) };
+  static const model_t dg200_model = { "DG-200", 230400, false, false, dg200_commands, sizeof(dg200_commands) / sizeof(dg100_command) };
   model = &dg200_model;
+  this->isfile = isfile;
   common_rd_init(fname);
 }
 
-static void
-dg200_rd_serial_init(const QString& fname)
-{
-  isfile = false;
-  dg200_rd_init(fname);
-}
-
-static void
-dg200_rd_file_init(const QString& fname)
-{
-  isfile = true;
-  dg200_rd_init(fname);
-}
-
-static void
-dg100_rd_deinit()
+void
+Dg100Format::rd_deinit()
 {
   if (isfile) {
     gbfclose(fin);
@@ -770,8 +686,8 @@ dg100_rd_deinit()
   }
 }
 
-static void
-dg100_read()
+void
+Dg100Format::read()
 {
   if (*erase_only == '1') {
     dg100_erase();
@@ -782,92 +698,3 @@ dg100_read()
     dg100_erase();
   }
 }
-
-/**************************************************************************/
-
-// capabilities below means: we can read tracks and waypoints
-
-ff_vecs_t dg100_vecs = {
-  ff_type_serial,
-  {
-    ff_cap_read                        /* waypoints */,
-    ff_cap_read                        /* tracks */,
-    ff_cap_none                        /* routes */
-  },
-  dg100_rd_serial_init,
-  nullptr,
-  dg100_rd_deinit,
-  nullptr,
-  dg100_read,
-  nullptr,
-  nullptr,
-  &dg100_args,
-  CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
-  /* not fixed, can be changed through command line parameter */
-  , NULL_POS_OPS,
-  nullptr
-};
-
-ff_vecs_t dg100_fvecs = {
-  ff_type_internal, /* This is a regression test, hide from GUI. */
-  {
-    ff_cap_read                        /* waypoints */,
-    ff_cap_read                        /* tracks */,
-    ff_cap_none                        /* routes */
-  },
-  dg100_rd_file_init,
-  nullptr,
-  dg100_rd_deinit,
-  nullptr,
-  dg100_read,
-  nullptr,
-  nullptr,
-  &dg100_args,
-  CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
-  /* not fixed, can be changed through command line parameter */
-  , NULL_POS_OPS,
-  nullptr
-};
-
-ff_vecs_t dg200_vecs = {
-  ff_type_serial,
-  {
-    ff_cap_read                        /* waypoints */,
-    ff_cap_read                        /* tracks */,
-    ff_cap_none                        /* routes */
-  },
-  dg200_rd_serial_init,
-  nullptr,
-  dg100_rd_deinit,
-  nullptr,
-  dg100_read,
-  nullptr,
-  nullptr,
-  &dg100_args,
-  CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
-  /* not fixed, can be changed through command line parameter */
-  , NULL_POS_OPS,
-  nullptr
-};
-
-ff_vecs_t dg200_fvecs = {
-  ff_type_internal, /* This is a regression test, hide from GUI. */
-  {
-    ff_cap_read                        /* waypoints */,
-    ff_cap_read                        /* tracks */,
-    ff_cap_none                        /* routes */
-  },
-  dg200_rd_file_init,
-  nullptr,
-  dg100_rd_deinit,
-  nullptr,
-  dg100_read,
-  nullptr,
-  nullptr,
-  &dg100_args,
-  CET_CHARSET_ASCII, 0                 /* ascii is the expected character set */
-  /* not fixed, can be changed through command line parameter */
-  , NULL_POS_OPS,
-  nullptr
-};
-/**************************************************************************/
diff --git a/dg-100.h b/dg-100.h
new file mode 100644 (file)
index 0000000..c147a9c
--- /dev/null
+++ b/dg-100.h
@@ -0,0 +1,229 @@
+/*
+
+    GlobalSat DG-100/DG-200 GPS data logger download.
+
+    Copyright (C) 2007  Mirko Parthey, mirko.parthey@informatik.tu-chemnitz.de
+    Copyright (C) 2005-2008  Robert Lipe, robertlipe+source@gpsbabel.org
+    Copyright (C) 2012  Nicolas Boullis, nboullis@debian.org
+    Copyright (C) 2014  Jean-Claude Repetto, gpsbabel@repetto.org
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+
+ */
+
+/*
+    DG-100 / DG-200 communication protocol specification:
+    http://www.usglobalsat.com/s-176-developer-information.aspx
+ */
+#ifndef DG100_H_INCLUDED_
+#define DG100_H_INCLUDED_
+
+#include <cstdint>           // for uint8_t, int16_t, uint16_t
+#include <cstdio>            // for size_t
+
+#include <QtCore/QDateTime>  // for QDateTime
+#include <QtCore/QList>      // for QList
+#include <QtCore/QString>    // for QString
+#include <QtCore/QVector>    // for QVector
+
+#include "defs.h"
+#include "format.h"          // for Format
+#include "gbfile.h"          // for gbfile
+
+
+class Dg100Format : public Format
+{
+public:
+  /* Member Functions */
+
+  QVector<arglist_t>* get_args() override
+  {
+    return &dg100_args;
+  }
+
+  QVector<ff_cap> get_cap() const override
+  {
+    return {
+      ff_cap_read                      /* waypoints */,
+      ff_cap_read                      /* tracks */,
+      ff_cap_none                      /* routes */
+    };
+  }
+
+  QString get_encode() const override
+  {
+    return CET_CHARSET_ASCII;
+  }
+
+  int get_fixed_encode() const override
+  {
+    return 0;
+  }
+
+  void read() override;
+  void rd_deinit() override;
+
+protected:
+  /* Types */
+
+  enum dg100_command_id {
+    dg100cmd_getconfig     = 0xB7,
+    dg100cmd_setconfig     = 0xB8,
+    dg100cmd_getfileheader = 0xBB,
+    dg100cmd_getfile       = 0xB5,
+    dg100cmd_erase         = 0xBA,
+    dg100cmd_getid         = 0xBF,
+    dg100cmd_setid         = 0xC0,
+    dg100cmd_gpsmouse      = 0xBC,
+    dg200cmd_reset         = 0x80
+  };
+
+  struct dg100_command {
+    int  id;
+    int  sendsize;
+    int  recvsize;
+    int  trailing_bytes;
+    const char* text;  /* Textual description for debugging */
+  };
+
+  struct model_t {
+    const char* name;
+    unsigned speed;
+    bool has_trailing_bytes;
+    bool has_payload_end_seq;
+    const dg100_command* commands;
+    unsigned int numcommands;
+  };
+
+  /* Constants */
+
+  /* maximum frame size observed so far: 1817 bytes
+   *   (dg100cmd_getfileheader returning 150 entries)
+   * dg100cmd_getfileheader is the only answer type of variable length,
+   * answers of other types are always shorter than 1817 bytes */
+  static constexpr int FRAME_MAXLEN = 4096;
+
+  /* Member Functions */
+
+  const dg100_command* dg100_findcmd(int id) const;
+  static QDateTime bintime2utc(int date, int time);
+  static void dg100_debug(const char* hdr, int include_nl, size_t sz, unsigned char* buf);
+  static void dg100_log(const char* fmt, ...);
+  float bin2deg(int val) const;
+  void process_gpsfile(uint8_t* data, route_head** track) const;
+  static uint16_t dg100_checksum(const uint8_t* buf, int count);
+  size_t dg100_send(uint8_t cmd, const void* payload, size_t param_len) const;
+  int dg100_recv_byte() const;
+  int dg100_read_wait(void* handle, void* buf, unsigned int len, unsigned int ms) const;
+  int dg100_recv_frame(const dg100_command** cmdinfo_result, uint8_t** payload) const;
+  int dg100_recv(uint8_t expected_id, void* buf, unsigned int len) const;
+  int dg100_request(uint8_t cmd, const void* sendbuf, void* recvbuf, size_t count) const;
+  QList<int> dg100_getfileheaders() const;
+  void dg100_getconfig() const;
+  void dg100_getfile(int16_t num, route_head** track) const;
+  void dg100_getfiles() const;
+  int dg100_erase() const;
+  void common_rd_init(const QString& fname);
+  void dg100_rd_init(const QString& fname, bool isfile);
+  void dg200_rd_init(const QString& fname, bool isfile);
+
+  /* Data Members */
+
+  const model_t* model{nullptr};
+  void* serial_handle{nullptr};
+  gbfile* fin{nullptr};
+  bool isfile{false};
+
+  static const dg100_command dg100_commands[];
+  static const dg100_command dg200_commands[];
+
+  /* GPSBabel integration */
+
+  char* erase{nullptr};
+  char* erase_only{nullptr};
+
+  QVector<arglist_t> dg100_args = {
+    {
+      "erase", &erase, "Erase device data after download",
+      "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+    },
+    {
+      "erase_only", &erase_only, "Only erase device data, do not download anything",
+      "0", ARGTYPE_BOOL, ARG_NOMINMAX, nullptr
+    },
+  };
+
+};
+
+class Dg100SerialFormat : public Dg100Format
+{
+public:
+
+  ff_type get_type() const override
+  {
+    return ff_type_serial;
+  }
+
+  void rd_init(const QString& fname) override
+  {
+    dg100_rd_init(fname, false);
+  }
+};
+
+class Dg100FileFormat : public Dg100Format
+{
+public:
+
+  ff_type get_type() const override
+  {
+    return ff_type_internal;
+  }
+
+  void rd_init(const QString& fname) override
+  {
+    dg100_rd_init(fname, true);
+  }
+};
+
+class Dg200SerialFormat : public Dg100Format
+{
+public:
+
+  ff_type get_type() const override
+  {
+    return ff_type_serial;
+  }
+
+  void rd_init(const QString& fname) override
+  {
+    dg200_rd_init(fname, false);
+  }
+};
+
+class Dg200FileFormat : public Dg100Format
+{
+public:
+
+  ff_type get_type() const override
+  {
+    return ff_type_internal;
+  }
+
+  void rd_init(const QString& fname) override
+  {
+    dg200_rd_init(fname, true);
+  }
+};
+#endif // DG100_H_INCLUDED_
diff --git a/vecs.h b/vecs.h
index 33276b1d62932b0ad5cf2ac559173024a6431c87..0284b890d2aefb783819a062b21f2f33031c983f 100644 (file)
--- a/vecs.h
+++ b/vecs.h
@@ -28,6 +28,7 @@
 #include <QtCore/QVector>       // for QVector<>::iterator, QVector
 
 #include "defs.h"
+#include "dg-100.h"
 #include "format.h"
 #include "energympro.h"
 #include "garmin_fit.h"
@@ -130,10 +131,6 @@ extern ff_vecs_t g7towin_vecs;
 extern ff_vecs_t garmin_gpi_vecs;
 extern ff_vecs_t lmx_vecs;
 extern ff_vecs_t xol_vecs;
-extern ff_vecs_t dg100_vecs;
-extern ff_vecs_t dg100_fvecs;
-extern ff_vecs_t dg200_vecs;
-extern ff_vecs_t dg200_fvecs;
 extern ff_vecs_t navilink_vecs;
 extern ff_vecs_t ik3d_vecs;
 extern ff_vecs_t osm_vecs;
@@ -360,10 +357,10 @@ private:
   LegacyFormat lmx_fmt {lmx_vecs};
   RandomFormat random_fmt;
   LegacyFormat xol_fmt {xol_vecs};
-  LegacyFormat dg100_fmt {dg100_vecs};
-  LegacyFormat dg100_ffmt {dg100_fvecs};
-  LegacyFormat dg200_fmt {dg200_vecs};
-  LegacyFormat dg200_ffmt {dg200_fvecs};
+  Dg100SerialFormat dg100_fmt;
+  Dg100FileFormat dg100_ffmt;
+  Dg200SerialFormat dg200_fmt;
+  Dg200FileFormat dg200_ffmt;
   LegacyFormat navilink_fmt {navilink_vecs};
   LegacyFormat ik3d_fmt {ik3d_vecs};
   LegacyFormat osm_fmt {osm_vecs};